Skip to content

Conversation

Jack251970
Copy link
Member

Changes

  • Add Auto Update description
image
  • Add Auto Update Plugins option which can automatically check plugin updates in the background every 5 hours
Screenshot 2025-07-14 163214
  • Add an option to check plugin updates in plugin store page
Screenshot 2025-07-14 163239

Test

Screenshot 2025-07-14 163145 Screenshot 2025-07-14 163424

One more thing

Since the plugin update message is implemented with message instead of message box which I do not think it will annoy users, I use default True value for Auto Update Plugins.

@Jack251970 Jack251970 added this to the 2.0.0 milestone Jul 14, 2025
@Jack251970 Jack251970 added the enhancement New feature or request label Jul 14, 2025
Copy link

gitstream-cm bot commented Jul 14, 2025

Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

Copy link
Contributor

coderabbitai bot commented Jul 14, 2025

📝 Walkthrough
## Walkthrough

These changes introduce automated plugin update functionality to the application. A background process periodically checks for plugin updates if enabled in user settings, supports bulk updating of plugins, and adds corresponding UI elements and localization strings. New settings and commands allow users to control and trigger plugin update checks from the interface.

## Changes

| File(s)                                                                                      | Change Summary                                                                                      |
|---------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| Flow.Launcher.Core/Plugin/PluginInstaller.cs                                                | Added async method for checking and bulk updating plugins; supports silent and interactive modes. |
| Flow.Launcher.Infrastructure/UserSettings/Settings.cs                                       | Added `AutoUpdatePlugins` boolean property to user settings.                                      |
| Flow.Launcher/App.xaml.cs                                                                   | Added static background method for periodic plugin update checks; refactored related startup logic.|
| Flow.Launcher/Languages/en.xaml                                                             | Added localization strings for plugin update features and tooltips.                               |
| Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs                   | Added async command for checking plugin updates from the plugin store view model.                 |
| Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml                                   | Added toggle for auto plugin updates and improved update-related card group formatting.           |
| Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml                               | Added button to trigger plugin update checks in the plugin store UI.                              |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant App
    participant Settings
    participant PluginInstaller
    participant UI

    App->>Settings: Read AutoUpdatePlugins
    alt AutoUpdatePlugins enabled
        loop Every 5 hours
            App->>PluginInstaller: CheckForPluginUpdatesAsync(silent=true)
            PluginInstaller->>PluginInstaller: Update plugin manifest, compare versions
            alt Updates available
                PluginInstaller->>UI: Show update all plugins prompt
                User->>UI: Click "Update all plugins"
                UI->>PluginInstaller: UpdateAllPlugins()
                PluginInstaller->>PluginInstaller: Download and update plugins
            else No updates
                PluginInstaller->>UI: Optionally show no updates message
            end
        end
    end

Possibly related PRs

Suggested reviewers

  • taooceros

</details>

<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 77a7c6ec759c065ff757ca56a54ab6f771b219fd and 37d6cea2d32822c9b26ede0ee6f2b1a1e4cf5f63.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `Flow.Launcher.Core/Plugin/PluginInstaller.cs` (3 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (1)</summary>

* Flow.Launcher.Core/Plugin/PluginInstaller.cs

</details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Flow-Launcher/Flow.Launcher&utm_content=3827):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
Flow.Launcher.Core/Plugin/PluginInstaller.cs (2)

294-313: Consider refactoring the complex LINQ query for better readability.

The LINQ query for finding updatable plugins is quite complex and could benefit from being broken down into smaller, more readable parts. Consider extracting the version comparison logic into a separate method.

Here's a suggested refactor:

-        // Get all plugins that can be updated
-        var resultsForUpdate = (
-            from existingPlugin in API.GetAllPlugins()
-            join pluginUpdateSource in API.GetPluginManifest()
-                on existingPlugin.Metadata.ID equals pluginUpdateSource.ID
-            where string.Compare(existingPlugin.Metadata.Version, pluginUpdateSource.Version,
-                      StringComparison.InvariantCulture) <
-                  0 // if current version precedes version of the plugin from update source (e.g. PluginsManifest)
-                  && !API.PluginModified(existingPlugin.Metadata.ID)
-            select
-                new
-                {
-                    existingPlugin.Metadata.ID,
-                    pluginUpdateSource.Name,
-                    pluginUpdateSource.Author,
-                    CurrentVersion = existingPlugin.Metadata.Version,
-                    NewVersion = pluginUpdateSource.Version,
-                    existingPlugin.Metadata.IcoPath,
-                    PluginExistingMetadata = existingPlugin.Metadata,
-                    PluginNewUserPlugin = pluginUpdateSource
-                }).ToList();
+        // Get all plugins that can be updated
+        var resultsForUpdate = GetUpdatablePlugins().ToList();
+        
+        // Add private method:
+        private static IEnumerable<dynamic> GetUpdatablePlugins()
+        {
+            return from existingPlugin in API.GetAllPlugins()
+                   join pluginUpdateSource in API.GetPluginManifest()
+                       on existingPlugin.Metadata.ID equals pluginUpdateSource.ID
+                   where HasNewerVersion(existingPlugin.Metadata.Version, pluginUpdateSource.Version)
+                         && !API.PluginModified(existingPlugin.Metadata.ID)
+                   select CreateUpdateInfo(existingPlugin, pluginUpdateSource);
+        }
+        
+        private static bool HasNewerVersion(string currentVersion, string newVersion)
+        {
+            return string.Compare(currentVersion, newVersion, StringComparison.InvariantCulture) < 0;
+        }

284-284: Fix typo in XML documentation.

There's a typo in the parameter documentation.

-        /// <param name="silentUpdate">If true, do not show any messages when there is no udpate available.</param>
+        /// <param name="silentUpdate">If true, do not show any messages when there is no update available.</param>
Flow.Launcher/App.xaml.cs (1)

299-299: Consider adding more descriptive comment.

The comment could be more descriptive about what happens during plugin update checks.

-                    // check plugin updates every 5 hour
+                    // check plugin updates every 5 hours (silent mode - only shows notifications if updates are available)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42b2fd1 and 44fbc6e.

📒 Files selected for processing (7)
  • Flow.Launcher.Core/Plugin/PluginInstaller.cs (2 hunks)
  • Flow.Launcher.Infrastructure/UserSettings/Settings.cs (1 hunks)
  • Flow.Launcher/App.xaml.cs (4 hunks)
  • Flow.Launcher/Languages/en.xaml (4 hunks)
  • Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs (1 hunks)
  • Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml (4 hunks)
  • Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml (2)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs (2)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.
Flow.Launcher/App.xaml.cs (7)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Learnt from: taooceros
PR: Flow-Launcher/Flow.Launcher#2616
File: Flow.Launcher/Flow.Launcher.csproj:7-7
Timestamp: 2024-10-08T15:52:58.573Z
Learning: In the Flow Launcher project, the version number in the `Flow.Launcher.csproj` file is dynamically updated during the CI/CD process.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3672
File: Flow.Launcher/MainWindow.xaml.cs:318-318
Timestamp: 2025-06-08T14:12:12.842Z
Learning: In Flow.Launcher, the App.NotifyIcon static property is initialized in the App class before MainWindow creation, so null checks are not needed when accessing App.NotifyIcon in MainWindow lifecycle methods.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3672
File: Flow.Launcher/MainWindow.xaml.cs:244-247
Timestamp: 2025-06-08T14:12:21.348Z
Learning: In Flow.Launcher, App.NotifyIcon is created before MainWindow creation, so null checks for App.NotifyIcon are not necessary when accessing it from MainWindow code.
Learnt from: Yusyuriv
PR: Flow-Launcher/Flow.Launcher#3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.
Learnt from: jjw24
PR: Flow-Launcher/Flow.Launcher#2448
File: Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs:16-20
Timestamp: 2025-01-18T10:10:18.414Z
Learning: In Flow Launcher's plugin system, the PluginInitContext parameter passed to plugin constructors is guaranteed to be non-null by the plugin initialization system, making null checks unnecessary.
Flow.Launcher.Infrastructure/UserSettings/Settings.cs (4)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Learnt from: Yusyuriv
PR: Flow-Launcher/Flow.Launcher#3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.
Learnt from: taooceros
PR: Flow-Launcher/Flow.Launcher#2616
File: Flow.Launcher/Flow.Launcher.csproj:7-7
Timestamp: 2024-10-08T15:52:58.573Z
Learning: In the Flow Launcher project, the version number in the `Flow.Launcher.csproj` file is dynamically updated during the CI/CD process.
Flow.Launcher.Core/Plugin/PluginInstaller.cs (3)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.
Learnt from: taooceros
PR: Flow-Launcher/Flow.Launcher#2616
File: Flow.Launcher/Flow.Launcher.csproj:7-7
Timestamp: 2024-10-08T15:52:58.573Z
Learning: In the Flow Launcher project, the version number in the `Flow.Launcher.csproj` file is dynamically updated during the CI/CD process.
Flow.Launcher/Languages/en.xaml (5)
Learnt from: taooceros
PR: Flow-Launcher/Flow.Launcher#2616
File: Flow.Launcher/Flow.Launcher.csproj:7-7
Timestamp: 2024-10-08T15:52:58.573Z
Learning: In the Flow Launcher project, the version number in the `Flow.Launcher.csproj` file is dynamically updated during the CI/CD process.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Learnt from: onesounds
PR: Flow-Launcher/Flow.Launcher#3394
File: Flow.Launcher/Themes/Darker Glass.xaml:134-141
Timestamp: 2025-03-28T21:12:13.386Z
Learning: In Flow.Launcher, hotkey styling is implemented with a two-component structure: a Border element with style `ItemHotkeyBGStyle` that provides background and border styling, containing a TextBlock with style `ItemHotkeyStyle` that handles the text styling.
Learnt from: onesounds
PR: Flow-Launcher/Flow.Launcher#0
File: :0-0
Timestamp: 2025-04-23T15:14:49.986Z
Learning: In WPF applications like Flow.Launcher, font styling should be applied using implicit styles instead of setting the FontFamily property on individual controls. Define implicit styles in a ResourceDictionary using <Style TargetType="{x:Type Button}"> format and merge it into App.xaml, which automatically applies the font to all instances of the control type while still allowing explicit overrides where needed.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3672
File: Flow.Launcher/MainWindow.xaml.cs:318-318
Timestamp: 2025-06-08T14:12:12.842Z
Learning: In Flow.Launcher, the App.NotifyIcon static property is initialized in the App class before MainWindow creation, so null checks are not needed when accessing App.NotifyIcon in MainWindow lifecycle methods.
🧬 Code Graph Analysis (1)
Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs (3)
Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs (1)
  • RelayCommand (62-79)
Flow.Launcher/ViewModel/MainViewModel.cs (2)
  • RelayCommand (327-335)
  • RelayCommand (337-349)
Flow.Launcher.Core/Plugin/PluginInstaller.cs (5)
  • Task (34-113)
  • Task (120-159)
  • Task (166-214)
  • Task (222-279)
  • PluginInstaller (19-448)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: build
🔇 Additional comments (14)
Flow.Launcher.Core/Plugin/PluginInstaller.cs (1)

344-372: Good concurrent update implementation with proper error handling.

The implementation correctly uses Task.WhenAll for concurrent plugin updates and includes appropriate error handling for individual plugin update failures. The cancellation token usage and cleanup logic follow good practices.

Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml (1)

102-108: Clean UI implementation following existing patterns.

The new plugin update button is properly integrated into the existing UI with consistent styling, appropriate positioning, and correct command binding. The use of a tooltip and icon follows the established design patterns.

Flow.Launcher.Infrastructure/UserSettings/Settings.cs (1)

236-236: Well-positioned setting with appropriate default value.

The new AutoUpdatePlugins property is logically placed near other update-related settings and defaults to true, which aligns with the PR objective of making the feature non-intrusive by default.

Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs (1)

112-116: Clean command implementation following established patterns.

The new CheckPluginUpdatesAsync command properly uses the [RelayCommand] attribute and calls the appropriate PluginInstaller method with silentUpdate: false, which is correct for user-initiated update checks.

Flow.Launcher/App.xaml.cs (2)

255-255: Good refactoring to static methods for consistency.

Converting AutoStartup and AutoUpdates to static methods improves consistency since they only use static fields and don't require instance state.

Also applies to: 276-276


293-308: Well-implemented automatic plugin update functionality.

The AutoPluginUpdates method correctly follows the same pattern as AutoUpdates, using PeriodicTimer for consistent 5-hour intervals. The implementation properly respects the user setting and runs the update check both on startup and periodically.

Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml (5)

185-186: LGTM: Tooltip binding properly added.

The tooltip binding for the auto-updates card follows the existing pattern and provides helpful user guidance.


245-245: Correct card type adjustment for new grouping.

Properly changed from "Last" to "Middle" to accommodate the new "autoUpdatePlugins" card being added to the group.


252-261: Well-structured auto-update plugins card implementation.

The new card follows the established pattern with proper:

  • Localization key bindings for title and tooltip
  • Consistent icon usage (matching the auto-updates card)
  • Proper binding to Settings.AutoUpdatePlugins
  • Correct "Last" card type for the group

402-404: Appropriate visibility binding for conditional UI.

The visibility binding correctly shows the "ShouldUseDoublePinyin" card only when pinyin is enabled, improving the user experience by hiding irrelevant options.


415-416: Logical visibility binding for double pinyin schema.

Properly shows the schema selection only when double pinyin is enabled, maintaining a clean and contextual UI.

Flow.Launcher/Languages/en.xaml (3)

96-96: Clear and informative tooltip text.

The tooltip effectively explains the auto-update functionality to users, setting proper expectations about automatic checking and notification behavior.


154-155: Consistent plugin auto-update strings.

The title and tooltip follow the same pattern as the main auto-update feature, maintaining consistency in terminology and user messaging.


237-241: Comprehensive plugin update UI strings.

The new strings provide complete localization support for the plugin update checking feature:

  • Clear status messages for both "no updates" and "updates available" scenarios
  • Actionable button text for updating all plugins
  • Helpful tooltip for the check updates functionality

All strings follow the established tone and style of the application.

<system:String x:Key="typingStartEn">Always Start Typing in English Mode</system:String>
<system:String x:Key="typingStartEnTooltip">Temporarily change your input method to English mode when activating Flow.</system:String>
<system:String x:Key="autoUpdates">Auto Update</system:String>
<system:String x:Key="autoUpdatesTooltip">Automatically check app updates and notify if there are any updates available</system:String>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This auto update for the app actually updates so the description needs a bit more specific.

Copy link

gitstream-cm bot commented Jul 15, 2025

🥷 Code experts: onesounds

Jack251970, onesounds have most 👩‍💻 activity in the files.
onesounds, Jack251970 have most 🧠 knowledge in the files.

See details

Flow.Launcher.Core/Plugin/PluginInstaller.cs

Activity based on git-commit:

Jack251970 onesounds
JUL 18 additions & 9 deletions
JUN 311 additions & 3 deletions
MAY
APR
MAR
FEB

Knowledge based on git-blame:
Jack251970: 89%

Flow.Launcher.Infrastructure/UserSettings/Settings.cs

Activity based on git-commit:

Jack251970 onesounds
JUL 44 additions & 4 deletions
JUN 4 additions & 2 deletions
MAY 86 additions & 30 deletions 5 additions & 3 deletions
APR 34 additions & 83 deletions 104 additions & 38 deletions
MAR 142 additions & 94 deletions 10 additions & 0 deletions
FEB 10 additions & 4 deletions

Knowledge based on git-blame:
Jack251970: 34%
onesounds: 16%

Flow.Launcher/App.xaml.cs

Activity based on git-commit:

Jack251970 onesounds
JUL 4 additions & 1 deletions
JUN 6 additions & 0 deletions
MAY 51 additions & 28 deletions
APR 73 additions & 40 deletions 3 additions & 0 deletions
MAR 168 additions & 94 deletions
FEB 79 additions & 40 deletions

Knowledge based on git-blame:
Jack251970: 69%

Flow.Launcher/Languages/en.xaml

Activity based on git-commit:

Jack251970 onesounds
JUL 8 additions & 5 deletions
JUN 21 additions & 0 deletions 7 additions & 6 deletions
MAY 33 additions & 4 deletions 15 additions & 2 deletions
APR 22 additions & 21 deletions 45 additions & 23 deletions
MAR 67 additions & 42 deletions 8 additions & 3 deletions
FEB 15 additions & 9 deletions

Knowledge based on git-blame:
onesounds: 40%
Jack251970: 16%

Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs

Activity based on git-commit:

Jack251970 onesounds
JUL
JUN 43 additions & 12 deletions
MAY 2 additions & 2 deletions
APR 97 additions & 10 deletions
MAR
FEB 6 additions & 4 deletions

Knowledge based on git-blame:
Jack251970: 83%

Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml

Activity based on git-commit:

Jack251970 onesounds
JUL 20 additions & 27 deletions
JUN 26 additions & 14 deletions 50 additions & 36 deletions
MAY 62 additions & 11 deletions
APR 11 additions & 8 deletions 130 additions & 69 deletions
MAR 44 additions & 20 deletions 43 additions & 62 deletions
FEB 1 additions & 1 deletions

Knowledge based on git-blame:
onesounds: 57%
Jack251970: 21%

Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml

Activity based on git-commit:

Jack251970 onesounds
JUL
JUN 7 additions & 0 deletions
MAY
APR 118 additions & 86 deletions 27 additions & 28 deletions
MAR
FEB

Knowledge based on git-blame:
onesounds: 73%
Jack251970: 23%

✨ Comment /gs review for LinearB AI review. Learn how to automate it here.

This comment has been minimized.

@jjw24 jjw24 enabled auto-merge July 15, 2025 12:02
Copy link
Member

@jjw24 jjw24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link

@check-spelling-bot Report

🔴 Please review

See the 📂 files view, the 📜action log, or 📝 job summary for details.

❌ Errors and Warnings Count
❌ forbidden-pattern 13
⚠️ non-alpha-in-dictionary 2

See ❌ Event descriptions for more information.

If the flagged items are 🤯 false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it,
    try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

@jjw24 jjw24 merged commit fa6301b into dev Jul 15, 2025
14 checks passed
@jjw24 jjw24 deleted the plugin_update branch July 15, 2025 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants